/**
 * \file SampleCAI.cpp
 *
 * \brief DLL Exports for SampleCAI.dll
 *
 * $Id: SampleCAI.cpp,v 1.2 2008/04/26 16:04:24 mgh Exp $
 *
 *
 * Copyright (C) 2006, 2008 Michael G. Herstine <sp1ff@pobox.com>
 *
 * Permission to use, copy, or modify this source code is hereby granted
 * free of  charge, provided  that this copyright  notice appear  on all
 * copies  and  on   all  source  code  derived  from   this  code.   No
 * representation is made regarding the suitability of this software for
 * any  purpose.  It  is provided  "as  is" without  express or  implied
 * warranty.
 *
 *
 */

#include "stdafx.h"             // Pre-compiled header
#include "resource.h"           // Resource definitions
#include "AddIn.h"              // For class CAddIn
#include "SampleCAI.h"          // MIDL-generated COM bindings

#include <initguid.h>           // Toggle the 'DEFINE_GUID' macro to
                                // definition, rather than just
                                // declaration...
DEFINE_GUID(IID_IDSAddIn, 0xc0002f81, 0xae2e, 0x11cf, 0xad, 0x7, 0x0,
            0xa0, 0xc9, 0x3, 0x49, 0x65);

// {8EA3F900-4A9F-11cf-8E4E-00AA004254C4}
DEFINE_GUID(IID_IApplicationEvents,
0x8ea3f900, 0x4a9f, 0x11cf, 0x8e, 0x4e, 0x0, 0xaa, 0x0, 0x42, 0x54, 0xc4);

// {2A6DF201-8240-11CF-AB59-00AA00C091A1}
DEFINE_GUID(IID_ITextDocument,
0x2A6DF201L,0x8240,0x11CF,0xAB,0x59,0x00,0xAA,0x00,0xC0,0x91,0xA1);

// {05092F20-833F-11CF-AB59-00AA00C091A1}
DEFINE_GUID(IID_ITextSelection,
0x05092F20L,0x833F,0x11CF,0xAB,0x59,0x00,0xAA,0x00,0xC0,0x91,0xA1);

// {08541520-83D3-11CF-AB59-00AA00C091A1}
DEFINE_GUID(IID_ITextWindow,
0x08541520L,0x83D3,0x11CF,0xAB,0x59,0x00,0xAA,0x00,0xC0,0x91,0xA1);

CSampleCAIModule _AtlModule;

CTraceCategory atlTraceSampleCAI("SampleCAI", 1);

// DLL Entry Point
extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance,
                               DWORD dwReason,
                               LPVOID lpReserved)
{
  if (DLL_PROCESS_ATTACH == dwReason)
  {
    hInstance;
# ifdef _DEBUG
    CTrace::s_trace.SetLevel(SAMPLE_CAI_DEBUG_LOG_LEVEL);
    ATLTRACE2(atlTraceCOM, 3, "SampleCAI.dll loading (0x%08x).\n", hInstance);
# endif // _DEBUG
  }
  else if (DLL_PROCESS_DETACH == dwReason)
  {
    ATLTRACE2(atlTraceCOM, 3, "SampleCAI.dll un-loading.\n");

  }

  return _AtlModule.DllMain(dwReason, lpReserved);
}



// Used to determine whether the DLL can be unloaded by OLE
STDAPI DllCanUnloadNow(void)
{
  ATLTRACE2(atlTraceCOM, 3, "SampleCAI.dll unloading\n");
  return _AtlModule.DllCanUnloadNow();
}


// Returns a class factory to create an object of the requested type
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
{
    return _AtlModule.DllGetClassObject(rclsid, riid, ppv);
}


/**
 * \brief Adds entries to the system registry
 *
 *
 * \return S_OK on success, a stock error code otherwise
 *
 *
 * This method  will register  our COM component  (CoAddIn), as  well as
 * handling self-registration for our  target hosts.  This should really
 * be handled by an installer program,  but since this is sample code, I
 * didn't  bother.  This  function will  manually check  the appropriate
 * Registry  location for  each known  host before  self-registering (to
 * avoid  making useless Registry  entries if  the host  machine doesn't
 * have, say, VS 2003, installed).
 *
 *
 */

STDAPI DllRegisterServer()
{
  HRESULT hr = S_OK;

  // Register the COM component, first.
  hr = _AtlModule.DllRegisterServer();
  if (FAILED(hr)) return hr;

  // Next, conditionally self-register for each host type of which we're
  // aware:
  CRegKey hKey;

  //////////////////////////////////////////////////////////////////////
  //                          DevStudio 6                             //
  //////////////////////////////////////////////////////////////////////

  LONG lStatus = hKey.Open(HKEY_CURRENT_USER, _T("Software\\Microsoft")
                           _T("\\DevStudio\\6.0\\AddIns"));
  if (ERROR_SUCCESS == lStatus)
  {
    ATLTRACE2(atlTraceRegistrar, 3, "This server will be registered as"
              " a DevStudio 6 AddIn.");
    hr = _AtlModule.UpdateRegistryFromResourceS(IDR_DEVSTUDIO, TRUE);
    if (FAILED(hr)) return hr;
  }

  //////////////////////////////////////////////////////////////////////
  //                       Visual Studio 2003                         //
  //////////////////////////////////////////////////////////////////////

  // We determine app existence by inspecting the root key.  I've seen
  // new VisualStudio installations that don't create the "AddIns"
  // sub-key.
  lStatus = hKey.Open(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Vi")
                      _T("sualStudio\\7.1"));
  if (ERROR_SUCCESS == lStatus)
  {
    ATLTRACE2(atlTraceRegistrar, 3, "This server will be registered as"
              " a Visual Studio 2003 AddIn.");

    lStatus = hKey.Create( hKey.m_hKey, "AddIns" );
    if (ERROR_SUCCESS == lStatus)
    {
      hr = _AtlModule.UpdateRegistryFromResourceS(IDR_VS2003, TRUE);
      if (FAILED(hr)) return hr;
    }
  }

  //////////////////////////////////////////////////////////////////////
  //                       Visual Studio 2005                         //
  //////////////////////////////////////////////////////////////////////

  // We determine app existence by inspecting the root key.  I've seen
  // new VisualStudio installations that don't create the "AddIns"
  // sub-key.
  lStatus = hKey.Open(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Vi")
                      _T("sualStudio\\8.0"));
  if (ERROR_SUCCESS == lStatus)
  {
    ATLTRACE2(atlTraceRegistrar, 3, "This server will be registered as"
              " a Visual Studio 2005 AddIn.");

    lStatus = hKey.Create( hKey.m_hKey, "AddIns" );
    if (ERROR_SUCCESS == lStatus)
    {
      hr = _AtlModule.UpdateRegistryFromResourceS(IDR_VS2005, TRUE);
      if (FAILED(hr)) return hr;
    }
  }

  //////////////////////////////////////////////////////////////////////
  //                       Visual Studio 2008                         //
  //////////////////////////////////////////////////////////////////////

  // We determine app existence by inspecting the root key.  I've seen
  // new VisualStudio installations that don't create the "AddIns"
  // sub-key.
  lStatus = hKey.Open(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Vi")
                      _T("sualStudio\\9.0"));
  if (ERROR_SUCCESS == lStatus)
  {
    ATLTRACE2(atlTraceRegistrar, 3, "This server will be registered as"
              " a Visual Studio 2008 AddIn.");

    lStatus = hKey.Create( hKey.m_hKey, "AddIns" );
    if (ERROR_SUCCESS == lStatus)
    {
      hr = _AtlModule.UpdateRegistryFromResourceS(IDR_VS2008, TRUE);
      if (FAILED(hr)) return hr;
    }
  }

  //////////////////////////////////////////////////////////////////////
  //                          Office 2003                             //
  //////////////////////////////////////////////////////////////////////

  lStatus = hKey.Open(HKEY_CURRENT_USER, _T("Software\\Microsoft\\Of")
                      _T("fice"));
  if (ERROR_SUCCESS == lStatus)
  {
    ATLTRACE2(atlTraceRegistrar, 3, "This server will be registered as"
              " an Excel 2003 AddIn.");
    hr = _AtlModule.UpdateRegistryFromResourceS(IDR_EXCEL2003, TRUE);
    if (FAILED(hr)) return hr;
  }

  // Later: Add other applications here...

  return hr;

} // End DllRegisterServer.


// DllUnregisterServer - Removes entries from the system registry
STDAPI DllUnregisterServer(void)
{
  HRESULT hr = S_OK;

  _AtlModule.DllUnregisterServer();

  _AtlModule.UpdateRegistryFromResourceS(IDR_DEVSTUDIO, FALSE);
  _AtlModule.UpdateRegistryFromResourceS(IDR_VS2003,    FALSE);
  _AtlModule.UpdateRegistryFromResourceS(IDR_VS2005,    FALSE);
  _AtlModule.UpdateRegistryFromResourceS(IDR_EXCEL2003, FALSE);
  _AtlModule.UpdateRegistryFromResourceS(IDR_VS2008,    FALSE);

  // Later: Add other applications here...

  CRegKey hKey;
  LONG lStatus = hKey.Open(HKEY_CURRENT_USER, SOFTWARE);
  if (ERROR_SUCCESS == lStatus)
  {
    lStatus = hKey.Open(hKey, SAMPLES);
    if (ERROR_SUCCESS == lStatus)
    {
      hKey.RecurseDeleteKey(SAMPLECAI);
    }
  }

  return hr;

} // End DllUnregisterServer.

// Local Variables:
// fill-column: 72
// indent-tabs-mode: nil
// show-trailing-whitespace: t
// End:

// SampleCAI.cpp ends here.
